package com.wtwd.campus.fjryE15.service.impl;

import com.wtwd.campus.common.Constants;
import com.wtwd.campus.common.RespCode;
import com.wtwd.campus.entity.DeviceInfo;
import com.wtwd.campus.entity.DeviceSOSList;
import com.wtwd.campus.entity.DeviceWhiteCall;
import com.wtwd.campus.entity.DeviceWhiteList;
import com.wtwd.campus.fjryE15.entity.FjryRespCode;
import com.wtwd.campus.fjryE15.entity.PhoneData;
import com.wtwd.campus.fjryE15.entity.PhoneDatas;
import com.wtwd.campus.fjryE15.entity.vo.AuthSetSpecialNum;
import com.wtwd.campus.fjryE15.enumeration.PhoneEnum;
import com.wtwd.campus.fjryE15.service.DeviceService;
import com.wtwd.campus.fjryE15.service.PhoneService;
import com.wtwd.campus.hxy.service.CommandRecordService;
import com.wtwd.campus.service.DeviceInfoService;
import com.wtwd.campus.service.RedisService;
import com.wtwd.campus.service.SosCallService;
import com.wtwd.campus.service.WhiteListService;
import com.wtwd.campus.utils.CommandNumberUtil;
import com.wtwd.campus.utils.CommandSendUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author mjy
 * @date 2022/09/19
 * @description
 */
@Service("fjryPhoneService")
public class phoneServiceImpl implements PhoneService {

    @Resource
    private CommandSendUtils commandSendUtils;

    @Resource
    private DeviceInfoService deviceInfoService;

    @Resource
    private CommandRecordService commandRecordService;

    @Resource
    private RedisService redisService;

    @Resource
    private WhiteListService whiteListService;

    @Resource
    private SosCallService sosCallService;

    @Value("${h5.customerId.ryh5}")
    private Integer ryh5CustomerId;

    @Resource
    private DeviceService deviceService;

    @Override
    public AuthSetSpecialNum AuthSetSpecialNum(String imei, List<PhoneData> sosLists, List<PhoneData> familyLists, List<PhoneData> whiteLists) {
        AuthSetSpecialNum authSetSpecialNum = new AuthSetSpecialNum();
        if (!deviceService.authDeviceIsExist(imei)){
            authSetSpecialNum.setRest(false);
            authSetSpecialNum.setRespCode(FjryRespCode.DEVICE_NOT_EXIST);
            return authSetSpecialNum;
        }
        boolean online = commandSendUtils.deviceOnline(imei);
        if (!online) {
            authSetSpecialNum.setRest(false);
            authSetSpecialNum.setRespCode(FjryRespCode.DEVICE_NOT_ONLINE);
            return authSetSpecialNum;
        }
        if (familyLists != null && familyLists.size() > PhoneEnum.FAMILY_PHONE.getMaxLength()) {
            authSetSpecialNum.setRest(false);
            authSetSpecialNum.setRespCode(FjryRespCode.FAMILY_PONE_CEILING);
            return authSetSpecialNum;
        }
        if (sosLists != null && sosLists.size() > PhoneEnum.SOS_PHONE.getMaxLength()) {
            authSetSpecialNum.setRest(false);
            authSetSpecialNum.setRespCode(FjryRespCode.SOS_PONE_CEILING);
            return authSetSpecialNum;
        }
        if (whiteLists != null && whiteLists.size() > PhoneEnum.WHITE_PHONE.getMaxLength()) {
            authSetSpecialNum.setRest(false);
            authSetSpecialNum.setRespCode(FjryRespCode.WHITE_PONE_CEILING);
            return authSetSpecialNum;
        }
        authSetSpecialNum.setRest(true);
        authSetSpecialNum.setRespCode(FjryRespCode.SUCCESS);
        return authSetSpecialNum;
    }

    /**
     * 亲情号白名单采用一条指令处理
     * 指令关键字 PBWLALL
     *
     * @param deviceId
     * @param imei
     * @param sosLists
     * @param familyLists
     * @param whiteLists
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean sendPhone(Integer deviceId, String imei, List<PhoneData> sosLists, List<PhoneData> familyLists, List<PhoneData> whiteLists) {
        deleteCacheCmd(imei, Constants.ALL_WHITELIST_NUMBER);
        deleteCacheCmd(imei, Constants.ALL_SOS_PHONE);
        clearPhoneData(deviceId);
        String commandNumber = CommandNumberUtil.getCurTime();
        List<DeviceWhiteCall> dealFamilyLists = dealFamilyLists(deviceId, imei, familyLists, commandNumber);
        List<DeviceWhiteCall> deviceWhiteCalls = dealWhiteLists(deviceId, imei, familyLists, commandNumber);
        dealFamilyLists.addAll(deviceWhiteCalls);
        List<DeviceWhiteCall> deviceWhiteCallList = dealFamilyLists.stream().sorted(Comparator.comparing(DeviceWhiteCall::getSequence)).collect(Collectors.toList());
        List<Map<String, Object>> deviceWhiteCallMap = new ArrayList<>();
        for (DeviceWhiteCall deviceWhiteCall : deviceWhiteCallList) {
            Map<String, Object> map = new HashMap<>();
            map.put("name", deviceWhiteCall.getName());
            map.put("phone", deviceWhiteCall.getPhone());//将手机号记录为空
            map.put("sequence", deviceWhiteCall.getSequence());
            deviceWhiteCallMap.add(map);
        }
        try {
            commandSendUtils.setAllWhiteCall(deviceWhiteCallMap, imei, commandNumber, commandSendUtils.deviceOnline(imei), Constants.H5_COMMAND_USER_ID, false);
            String commandNumberSos = CommandNumberUtil.getCurTime();
            List<DeviceSOSList> deviceSOSLists = dealSosData(deviceId, imei, sosLists, commandNumberSos);
            //发送离线指令
            commandSendUtils.setAllSosCall(deviceSOSLists, imei, commandNumber, commandSendUtils.deviceOnline(imei), Constants.H5_COMMAND_USER_ID, false);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean deleteCacheCmd(String imei, String cmdPrefix) {
        redisService.deleteHashByPrefix(imei, cmdPrefix);
        return commandRecordService.deleteCacheCmd(imei, cmdPrefix) > 0 ? true : false;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean clearPhoneData(Integer deviceId) {
        whiteListService.deletePhoneByDeviceId(deviceId);
        sosCallService.deletePhoneByDeviceId(deviceId);
        return true;
    }

    @Override
    public PhoneDatas getPhonesByDeviceId(Integer deviceId) {
        List<PhoneData> sosData = new ArrayList<>();
        List<PhoneData> familyData = new ArrayList<>();
        List<PhoneData> whiteData = new ArrayList<>();
        List<DeviceWhiteList> whiteLists = whiteListService.getWhiteListByDeviceId(deviceId, null);
        whiteLists=whiteLists.stream().filter(e->e.getStatus().equals(Constants.DEVICE_WHITE_NORMAl)).collect(Collectors.toList());
        if (whiteLists != null && whiteLists.size() > 0) {
            whiteLists.stream().filter
                    (family -> (
                            family.getSequence() >= PhoneEnum.FAMILY_PHONE.getMinSequence() && family.getSequence() <= PhoneEnum.FAMILY_PHONE.getMaxSequence())
                    ).forEach(e -> {
                PhoneData phoneData = new PhoneData();
                phoneData.setPhone(e.getWhitePhone());
                phoneData.setUserName(e.getWhiteName());
                familyData.add(phoneData);
            });
            whiteLists.stream().filter
                    (whiteList -> (
                            whiteList.getSequence() >= PhoneEnum.WHITE_PHONE.getMinSequence() && whiteList.getSequence() <= PhoneEnum.WHITE_PHONE.getMaxSequence())
                    ).forEach(e -> {
                PhoneData phoneData = new PhoneData();
                phoneData.setPhone(e.getWhitePhone());
                phoneData.setUserName(e.getWhiteName());
                whiteData.add(phoneData);
            });
        }
        List<DeviceSOSList> deviceSosList = this.sosCallService.getSosCallService(deviceId);
        deviceSosList=deviceSosList.stream().filter(e->e.getStatus().equals(Constants.DEVICE_SOS_NORMAl)).collect(Collectors.toList());
        if (deviceSosList!=null&&deviceSosList.size()>0){
            deviceSosList.forEach(sos->{
                PhoneData phoneData = new PhoneData();
                phoneData.setPhone(sos.getSosPhone());
                phoneData.setUserName(sos.getSosName());
                sosData.add(phoneData);
            });
        }
        PhoneDatas phoneDatas = new PhoneDatas();
        phoneDatas.setFamilyList(familyData);
        phoneDatas.setSosList(sosData);
        phoneDatas.setWhiteList(whiteData);
        return phoneDatas;
    }

    /**
     * 处理sos数据
     * 并将号码添加数据库
     * 并返回执行发送数据
     *
     * @param sosLists
     * @return
     */
    private List<DeviceSOSList> dealSosData(Integer deviceId, String imei, List<PhoneData> sosLists, String commandNumber) {
        List<DeviceSOSList> bathDelDeviceSos = new ArrayList<>();
        for (Integer i = PhoneEnum.SOS_PHONE.getMinSequence(); i <= PhoneEnum.SOS_PHONE.getMaxSequence(); i++) {
            DeviceSOSList deviceSOSList = new DeviceSOSList();
            deviceSOSList.setDeviceId(deviceId);
            deviceSOSList.setSosPhone("");
            deviceSOSList.setStatus(Constants.CLASSES_PATTERN_STAY_ADD);
            deviceSOSList.setSosName("");
            deviceSOSList.setCommandNumber(commandNumber);
            deviceSOSList.setSequence(i);
            bathDelDeviceSos.add(deviceSOSList);
        }
        if (sosLists != null && sosLists.size() > 0) {
            for (int i = 0; i < sosLists.size(); i++) {
                DeviceSOSList deviceSOSList = bathDelDeviceSos.get(i);
                deviceSOSList.setSosPhone(sosLists.get(i).getPhone());
                deviceSOSList.setSosName(sosLists.get(i).getUserName());
            }
        }
        List<DeviceSOSList> bathAddSosData = bathDelDeviceSos.stream().filter(e -> StringUtils.isNotBlank(e.getSosName()) && StringUtils.isNotBlank(e.getSosPhone()))
                .collect(Collectors.toList());
        if (bathAddSosData != null && bathAddSosData.size() > 0) {
            sosCallService.bathAddDeviceSosCall(bathAddSosData);
        }
        return bathDelDeviceSos;
    }

    /**
     * 处理情亲号数据
     * 并添加数据库
     *
     * @param deviceId
     * @param familyLists
     * @return
     */
    private List<DeviceWhiteCall> dealFamilyLists(Integer deviceId, String imei, List<PhoneData> familyLists, String commandNumber) {
        List<DeviceWhiteCall> bathDelDeviceFamily = new ArrayList<>();
        for (Integer i = PhoneEnum.FAMILY_PHONE.getMinSequence(); i <= PhoneEnum.FAMILY_PHONE.getMaxSequence(); i++) {
            DeviceWhiteCall deviceWhiteCall = new DeviceWhiteCall();
            deviceWhiteCall.setDeviceId(deviceId);
            deviceWhiteCall.setImei(imei);
            deviceWhiteCall.setStatus(Constants.CLASSES_PATTERN_STAY_ADD);
            deviceWhiteCall.setCommandNumber(commandNumber);
            deviceWhiteCall.setSequence(i);
            deviceWhiteCall.setName("");
            deviceWhiteCall.setPhone("");
            deviceWhiteCall.setIsAffection(1);
            bathDelDeviceFamily.add(deviceWhiteCall);
        }
        if (familyLists != null && familyLists.size() > 0) {
            for (int i = 0; i < familyLists.size(); i++) {
                DeviceWhiteCall deviceFamilyList = bathDelDeviceFamily.get(i);
                deviceFamilyList.setPhone(familyLists.get(i).getPhone());
                deviceFamilyList.setName(familyLists.get(i).getUserName());
            }
        }
        List<DeviceWhiteCall> bathAddFamilyData = bathDelDeviceFamily.stream().filter(e -> StringUtils.isNotBlank(e.getPhone()) && StringUtils.isNotBlank(e.getName()))
                .collect(Collectors.toList());
        if (bathAddFamilyData != null && bathAddFamilyData.size() > 0) {
            whiteListService.bathAddWhiteCall(bathAddFamilyData);
        }
        return bathDelDeviceFamily;
    }

    /**
     * 处理白名单数据
     * 并添加数据库
     *
     * @param deviceId
     * @param whiteLists
     * @return
     */

    private List<DeviceWhiteCall> dealWhiteLists(Integer deviceId, String imei, List<PhoneData> whiteLists, String commandNumber) {
        List<DeviceWhiteCall> bathDelDeviceWhite = new ArrayList<>();
        for (Integer i = PhoneEnum.WHITE_PHONE.getMinSequence(); i <= PhoneEnum.WHITE_PHONE.getMaxSequence(); i++) {
            DeviceWhiteCall deviceWhiteCall = new DeviceWhiteCall();
            deviceWhiteCall.setDeviceId(deviceId);
            deviceWhiteCall.setImei(imei);
            deviceWhiteCall.setStatus(Constants.CLASSES_PATTERN_STAY_ADD);
            deviceWhiteCall.setCommandNumber(commandNumber);
            deviceWhiteCall.setSequence(i);
            deviceWhiteCall.setName("");
            deviceWhiteCall.setPhone("");
            deviceWhiteCall.setIsAffection(0);
            bathDelDeviceWhite.add(deviceWhiteCall);
        }
        if (whiteLists != null && whiteLists.size() > 0) {
            for (int i = 0; i < whiteLists.size(); i++) {
                DeviceWhiteCall deviceFamilyList = bathDelDeviceWhite.get(i);
                deviceFamilyList.setPhone(whiteLists.get(i).getPhone());
                deviceFamilyList.setName(whiteLists.get(i).getUserName());
            }
        }
        List<DeviceWhiteCall> bathAddWhiteData = bathDelDeviceWhite.stream().filter(e -> StringUtils.isNotBlank(e.getPhone()) && StringUtils.isNotBlank(e.getName()))
                .collect(Collectors.toList());
        if (bathAddWhiteData != null && bathAddWhiteData.size() > 0) {
            whiteListService.bathAddWhiteCall(bathAddWhiteData);
        }
        return bathDelDeviceWhite;
    }
}
